#ifndef __DBFILEPHYPAGEMANAGER_H
#define __DBFILEPHYPAGEMANAGER_H

#pragma once

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "io.h"
#include <fcntl.h>

#include "DBFileType.h"

using namespace std;

// declaration

class DBFilePhyPageManager
{
	static const int DEFAULT_PAGE_NUM = 100;
	static const int VALID_PID = -1;
	static const int LAST_FREE_PAGE = -2;

	int* freePageLink;	
							//freePageLink[pid] == -1: 
							//		this pid is a valid pid
							//freePageLink[pid] > 0: nextFreePage[pid]
							//		is then next free page
							//freePageLink[pid] < -2: this pid is the last
							//free page

	int pageNum;			//Num of page in this file

	int nextFreePage;		//Index of next free page

	FILE* dbfile;

	char curFilename[305];

	/**
	* Funtion Description :increase the file size
	* @para int newPageNum
	* new page number
	* by Author: Jimmy
	*/
	void IncreaseFileSize();

	/**
	* Funtion Description : Save the file head to file
	* by Author: Jimmy
	*/
	int SaveHead();

	/**
	* Funtion Description : Load the file head from file
	* by Author: Jimmy
	*/
	int LoadHead();

public:

	/**
	* Funtion Description :
	* Only one instance in the whole project
	* by Author: Jimmy
	*/
	DBFilePhyPageManager(void);

	/**
	* Funtion Description :
	* by Author: Jimmy
	*/
	~DBFilePhyPageManager(void);

	/**
	* Funtion Description :Open A DB file, if not exist, create it
	* @para char* filename
	* DB file name
	* @para DBFileSystem* fileSystem
	* DBFileSystem we create from file head
	* @return int
	* -1: Open fail
	* 0: Open success
	* by Author: Jimmy
	*/
	int OpenDBFile(char* filename);

	/**
	* Funtion Description :Close The DB file currently open
	* @para DBFileSystem* fileSystem
	* DBFileSystem we create from file head
	* @return int
	* -1: Open fail
	* 0: Open success
	* by Author: Jimmy
	*/
	int CloseDBFile();

	/**
	* Funtion Description : Read A page from disk
	* @para int pid
	* Page's pid
	* @para DBBufPage* page
	* The corresponding memory page 
	* @return int
	* -1: fail
	* 0: success
	* by Author: Jimmy
	*/
	int DBReadPage(int pid, DBDiskPage* page);

	/**
	* Funtion Description : Write A page from disk
	* @para int pid
	* Page's pid
	* @para DBBufPage* page
	* The memory page to write
	* @return int
	* -1: fail
	* 0: success
	* by Author: Jimmy
	*/
	int DBWritePage(int pid, DBDiskPage* page);

	/**
	* Funtion Description :Alloc A new Page
	* @return int
	* >0: pid alloc
	* -1: alloc fail
	* by Author: Jimmy
	*/
	int DBAllocPage();

	/**
	* Funtion Description :Delete A page
	* @para int pid
	* page id of deleted page
	* @return int
	* 0: success
	* -1: fail
	* by Author: Jimmy
	*/
	int DBDeletePage(int pid);

	/**
	* Funtion Description : Is this pid valid
	* @para int pid
	* Page's pid
	* @return bool
	* true: pid valid
	* false: pid not valid
	* by Author: Jimmy
	*/
	inline bool IsExist(int pid)
	{
		if(pid >= pageNum)
			return false;
		return freePageLink[pid] == -1;
	}
};

#endif